package cn.bugstack.springframework.beans.factory.support;

import cn.bugstack.springframework.beans.factory.DisposableBean;
import cn.bugstack.springframework.beans.factory.config.SingletonBeanRegistry;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>通用的注册表实现
 *
 * @author Yaxi.Zhang
 * @since 2022/12/12 10:20
 */
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {

    /**
     * <p>Internal marker for a null singleton object:
     * used as marker value for concurrent Maps (which don't support null values).
     * <p>用作不支持空值的concurrent Maps的标记值
     * <p>可以把它当做 null 来处理，认为 NULL_OBJECT 就是 null 值的标记
     */
    protected static final Object NULL_OBJECT = new Object();

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();

    private final Map<String, DisposableBean> disposableBeans = new ConcurrentHashMap<>();

    @Override
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }

    @Override
    public void registerSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
    }

    public void registerDisposableBean(String beanName, DisposableBean bean) {
        disposableBeans.put(beanName, bean);
    }

    protected Map<String, DisposableBean> getDisposableBeans() {
        return disposableBeans;
    }

    // 这里和书上的实现方式不太相同
    // /**
    //  * <p>子类 {@link AbstractBeanFactory} 继承该方法作为
    //  * {@link cn.bugstack.springframework.beans.factory.config.ConfigurableBeanFactory} 的实现
    //  */
    // public void destroySingletons() {
    //     Set<String> keySet = this.disposableBeans.keySet();
    //     for (String beanName : keySet) {
    //         DisposableBean disposableBean = disposableBeans.remove(beanName);
    //         try {
    //             disposableBean.destroy();
    //         } catch (Exception e) {
    //             throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e);
    //         }
    //     }
    // }

}
